package service

import (
	"fmt"
	"go-project/common"
	"go-project/dto/requrest"
	"go-project/dto/response"
	"go-project/models"
)

type ArticleComment struct {
}

func (ArticleComment) FindLists(req *requrest.ArticleCommentSearchRequest) (lists []*response.ArticleCommentListResponse, count uint, err error) {
	offset := (req.Pagination.Page - 1) * req.Pagination.Limit
	var articleComment *models.ArticleComment
	query := common.DB.Table(articleComment.TableName())
	if len(req.ArticleName) > 0 {
		query = query.Where(" like ?", fmt.Sprintf("%%%s%%", req.ArticleName))
	}
	query.Model(articleComment).Select("count(id)").Count(&count)
	err = query.Select("articles.title as article_name,article_comments.id,article_comments.article_id,article_comments.content,article_comments.uid,article_comments.upvote_count,article_comments.downvote_count,article_comments.author_type,article_comments.reply_id,article_comments.created_at").Joins("left join articles  on articles.id = article_comments.article_id").Order("article_comments.id desc").Limit(req.Pagination.Limit).Offset(offset).Where("article_comments.deleted_at IS NULL").Where("article_comments.reply_id= ?", req.Pid).Scan(&lists).Error
	var userArray = make([]uint, 0, 10)
	var adminArray = make([]uint, 0, 10)
	var articleComment1 models.ArticleComment
	for _, v := range lists {
		result := query.Model(articleComment).Select("id").First(&articleComment1, "reply_id=?", v.ID)
		if result.RecordNotFound() {
			v.IsChildren = 0
		} else {
			v.IsChildren = 1
		}
		if v.AuthorType == 1 {
			adminArray = append(adminArray, v.Uid)
		} else {
			userArray = append(userArray, v.Uid)
		}
	}
	var admin models.Admin
	var user models.User
	var admins []models.Admin
	var users []models.User

	if len(userArray) > 0 {
		common.DB.Model(&user).Select("id,username").Where(userArray).Find(&users)
	}
	if len(adminArray) > 0 {
		common.DB.Model(&admin).Select("id,username").Where(adminArray).Find(&admins)
	}
	var userUsernameMap = make(map[uint]string)
	var adminUsernameMap = make(map[uint]string)

	if len(admins) > 0 {
		for _, row := range admins {
			adminUsernameMap[row.ID] = row.Username
		}
	}
	if len(users) > 0 {
		for _, row1 := range users {
			userUsernameMap[row1.ID] = row1.Username
		}
	}
	for _, v := range lists {
		if v.AuthorType == 1 {
			v.Username = adminUsernameMap[v.Uid]
		} else {
			v.Username = userUsernameMap[v.Uid]
		}
	}
	return
}

func (ArticleComment) Banned(commentID uint) (uint, error) {
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var articleComment *models.ArticleComment
	result := common.DB.First(articleComment, commentID)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	articleComment.IsBanned = 1
	res := common.DB.Save(articleComment)
	if err := res.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	err := articleComment.BannedChildComment(commentID)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return uint(res.RowsAffected), tx.Commit().Error
}

func (ArticleComment) Del(commentID uint) (uint, error) {
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var articleComment *models.ArticleComment
	result := common.DB.First(articleComment, commentID)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	res := common.DB.Delete(articleComment, commentID)
	if err := res.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	err := articleComment.BannedChildComment(commentID)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return uint(res.RowsAffected), tx.Commit().Error
}
